<!--
 * @Description: Table 组件简易封装了
 * @Author: wangchao
 * @Date: 2022-09-23 13:59:19
-->
<template>
  <div class="mytable-container">
    <el-table
      ref="tableRef"
      :data="tableData"
      style="width: 100%"
      :highlight-current-row="option.hlcr"
      @selection-change="handleSelectionChange"
      :border="option.isBorder"
    >
      <el-table-column type="selection" width="55" v-if="option.isSelection" />
      <el-table-column type="index" label="序号" width="60" v-if="option.isIndex" />
      <template v-for="(col, i) in option.columns">
        <el-table-column :property="col.property" :label="col.label" :width="col.width" v-if="col.type === 'opt'">
          <template #default="scope">
            <slot :name="`opt-${col.property}`" :scope="scope"></slot>
          </template>
        </el-table-column>
        <el-table-column :property="col.property" :label="col.label" :width="col.width" v-else>
          <template #default="{ row }">
            <el-popover effect="dark" trigger="hover" placement="top" width="auto" v-if="col.tipType === 'toolTip'">
              <template #default>
                <div> {{ row[col.property] }}</div>
              </template>
              <template #reference>
                <div class="ellipse">
                  {{ row[col.property] }}
                </div>
              </template>
            </el-popover>
            <div class="ellipse" v-else-if="col.tipType === 'windowFixed'" @mouseover="windowFixedFunc(row[col.property])" @mouseout="windowFixedFunc()">{{
              row[col.property]
            }}</div>
            <div v-else>{{ row[col.property] }}</div>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <div v-if="pagination" class="footer" :style="pagination?.footerStyle">
      <el-pagination
        :hide-on-single-page="true"
        v-model:currentPage="currentPage"
        background
        :layout="pagination?.layout ?? 'total,prev, pager, next, jumper'"
        :page-size="pagination?.pageSize ?? 5"
        :total="pageTotal"
        @current-change="pageChange"
      />
    </div>
  </div>
  <WindowFixedWrap v-show="tipInfo" :offset="[10, -30]">
    {{ tipInfo }}
  </WindowFixedWrap>
</template>
<script setup>
  // @ts-nocheck

  import WindowFixedWrap from '../WindowFixedWrap'

  const props = defineProps({
    option: {
      type: Object,
      default: {
        columns: [],
      },
    },
    outerKd: {
      type: Number,
      default: 0,
    },
  })
  const tipInfo = ref('')
  function windowFixedFunc(val = '') {
    tipInfo.value = val
  }
  const { option } = props
  const { outerKd } = toRefs(props)

  const kd = ref()
  const tableRef = ref()
  const tableData = ref()
  const multipleSelection = ref([])
  const pagination = ref()
  const dataParams = ref({}) // api请求的参数
  const currentPage = ref(1)

  watch(
    option,
    async (nv) => {
      if (!nv.columns) {
        throw new Error('必须传递columns')
      }
      pagination.value = nv.pagination
      await assembleDataParams(nv)
      requestData()
    },
    { deep: true, immediate: true },
  )

  // 组装请求参数
  function assembleDataParams(opt, mergeObj = {}) {
    let pag = opt?.pagination
    dataParams.value = {
      ...dataParams.value,
      ...mergeObj,
    }
    return new Promise((resolve) => {
      if (!opt) {
        return resolve(dataParams.value)
      }
      dataParams.value = {
        ...dataParams.value,
        ...(opt?.request?.apiData ?? {}),
      }
      if (pag) {
        dataParams.value = {
          ...dataParams.value,
          [pag?.numName ?? 'pageNum']: currentPage.value,
          [pag?.sizeName ?? 'pageSize']: pag.pageSize || 5,
        }
      }
      resolve(dataParams.value)
    })
  }
  // outerKd 格式：{val:xxx,kd:xxx} 一般用于传递参数data,和option分离可控性更高
  watch(
    outerKd,
    async (nv) => {
      currentPage.value = 1
      await assembleDataParams(null, {
        ...nv.val,
        [pagination.value?.numName ?? 'pageNum']: currentPage.value,
      })
      nv?.val && requestData()
    },
    { deep: true, immediate: false },
  )
  function handleSelectionChange(val) {
    multipleSelection.value = val
  }

  async function requestData() {
    // 守卫
    if (!option?.request?.api) {
      return null
    }
    const { api, apiUrl, apiMethod, postObj = { data: 'data', total: 'total' } } = option.request
    let res = await api({
      url: apiUrl,
      method: apiMethod,
      data: dataParams.value,
    })
    // let res = await new Promise((resolve) => {
    //   setTimeout(() => {
    //     resolve({
    //       d: {
    //         ddc: [
    //           {
    //             id: 1,
    //             carNumber: '京B20587',
    //             name: 'Tom',
    //             start: '2022/09/23 16:45:21',
    //             end: '2022/09/23 17:35:11',
    //           },
    //           {
    //             id: 2,
    //             carNumber: '京A20227',
    //             name: '李四',
    //             start: '2022/08/23 16:45:21',
    //             end: '2022/09/23 17:35:11',
    //           },
    //           {
    //             id: 3,
    //             carNumber: '京C45225',
    //             name: '王五',
    //             start: '2022/09/13 06:45:21',
    //             end: '2022/09/13 13:35:11',
    //           },
    //         ],
    //       },
    //       t: 16,
    //     })
    //   }, 2000)
    // })
    const { data: tbData, total } = postHandleFunc(postObj, res)
    tableData.value = tbData
    pageTotal.value = total
  }

  // 返回数据的后处理，按照规则兼容接口返回值 postObj: { data: 'd.ddc', total: 't' }
  function postHandleFunc(postObj = {}, res) {
    function recursionGet(res, keysStr) {
      let mks = keysStr.split('.')
      let final = res[mks[0]]
      for (let index = 1; index < mks.length; index++) {
        final = final[mks[index]]
      }
      return final
    }
    let result = {}
    for (const key in postObj) {
      result[key] = recursionGet(res, postObj[key])
    }
    return result
  }

  watch(kd, async () => {})

  const pageTotal = ref(0)
  async function pageChange(page) {
    currentPage.value = page
    await assembleDataParams(null, { [pagination.value?.numName ?? 'pageNum']: page })
    requestData()
  }

  defineExpose({
    multipleSelection,
    tableData,
  })
</script>
<style scoped lang="scss">
  @import '../index.scss';
  .mytable-container {
  }
</style>
